package com.sgj.shiro.realms;

import cn.hutool.core.collection.CollectionUtil;
import com.sgj.entity.Perms;
import com.sgj.entity.User;
import com.sgj.service.PermsService;
import com.sgj.service.UserService;
import com.sgj.utils.ApplicationContextUtils;
import com.sgj.utils.SerialSimpleByteSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.List;
import java.util.Objects;

/**
 * @Author: Guoji Shen
 * @Date: 2021/12/10 14:47
 */
@Slf4j
public class CustomerRealm extends AuthorizingRealm {

    // 授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取身份信息
        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        // 在工厂中获取 service 对象
        UserService userService = ApplicationContextUtils.getBean(UserService.class);
        User user = userService.findRolesByUserId(userService.findByUsername(primaryPrincipal).getId());

        if (CollectionUtil.isEmpty(user.getRoleList())) {
            throw new RuntimeException("该用户未绑定角色");
        }
        // 根据主身份信息获取角色和权限信息
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        user.getRoleList().forEach(role -> {
            simpleAuthorizationInfo.addRole(role.getName());

            // 赋予对应权限
            PermsService permsService = ApplicationContextUtils.getBean(PermsService.class);
            List<Perms> perms = permsService.findPermsByRoleId(role.getId());
            if (CollectionUtil.isNotEmpty(perms)) {
                perms.forEach(perm -> {
                    simpleAuthorizationInfo.addStringPermission(perm.getName());
                });
            }
        });
        return simpleAuthorizationInfo;
    }

    // 认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String principal = (String) token.getPrincipal();
        log.info("[CustomerRealmTest][AuthenticationInfo] 用户名为:{}", principal);
        // 在工厂中获取 service 对象
        UserService userService = ApplicationContextUtils.getBean(UserService.class);
        User user = userService.findByUsername(principal);
        if (Objects.isNull(user)) {
            throw new RuntimeException("该用户不存在");
        }
        if (principal.equals(user.getUsername())) {
            /**
             * 参数1：返回数据库中正确的用户名
             * 参数2：返回数据库中的正确密码
             * 参数3：随机盐
             * 参数4：提供当前realm的名字     this.getName();
             */
            return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), new SerialSimpleByteSource(user.getSalt()), this.getName());
        }
        return null;
    }
}